using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Zune.Forms
{
    /// <summary>
    /// A TabControl control.
    /// </summary>
    public class TabControl : Control
    {
        #region Private/Internal Members
        internal List<TabPage> _tabPages = new List<TabPage>();
        private bool _showHeader = true;
        internal int _headerHeight = 50; // Where the tab names are draw.
        private int _currentTabIndex = -1;
        private SpriteFont _font;
        private Color _shadowColor = Color.LightGray;
        private Texture2D _headerSeperatorLine;
        private Button _leftButton;
        private Button _rightButton;
        private Vector2 _startPos;
        private bool _touchChangedIndex = false;
        internal ContextMenu _contextMenu;
        //private bool _isMoving = false;
        internal Label _headerLabel;
        #endregion

        #region Constructors
        /// <summary>
        /// A TabControl.
        /// </summary>
        /// <param name="form">The Form that the TabControl belongs to.</param>
        public TabControl(Form form) : base(form)
        {
            base.ForeColor = Color.White;
            base.BackColor = Color.Black;
            base.Location = new Vector2(0, 0);
            base.Size = new Vector2(272, 480);
            form.Controls.Add(this);
            
            _leftButton = new Button(form);
            _leftButton.BackgroundImage = "arrow-left";
            _leftButton.BackgroundImagePressed = "arrow-left";
            _leftButton.Text = string.Empty;
            _leftButton.BorderType = Enumerations.BorderType.BorderNone;
            _leftButton.BackColor = base.BackColor;
            _leftButton.Clicked += new OnControlTouched(_leftButton_Clicked);

            _rightButton = new Button(form);
            _rightButton.BackgroundImage = "arrow-right";
            _rightButton.BackgroundImagePressed = "arrow-right";
            _rightButton.Text = string.Empty;
            _rightButton.BorderType = Enumerations.BorderType.BorderNone;
            _rightButton.BackColor = base.BackColor;
            _rightButton.Clicked += new OnControlTouched(_rightButton_Clicked);

            _headerLabel = new Label(form);
            _headerLabel.BorderType = Enumerations.BorderType.BorderNone;
            _headerLabel.AutoSize = false;
            _headerLabel.TextAlignment = Enumerations.TextAlignmentTypes.Center;
            _contextMenu = new ContextMenu(_headerLabel);
            _contextMenu.MenuItemClicked += new EventHandler(_contextMenu_MenuItemClicked);
        }
        #endregion

        #region Event Handlers
        protected void _contextMenu_MenuItemClicked(object sender, EventArgs e)
        {
            SelectedTabIndex = _tabPages.IndexOf(((TabPage)((MenuItem)sender).Value));
        }

        protected void _rightButton_Clicked(object sender, GameTime gameTime, TouchLocation touch)
        {
            SetNextTabPage();
        }

        protected void _leftButton_Clicked(object sender, GameTime gameTime, TouchLocation touch)
        {
            SetPreviousTabPage();
        }
        #endregion

        #region Overrides
        public override void LoadContent()
        {
            _font = base.Form.Content.Load<SpriteFont>("Tab");
            _headerSeperatorLine = Drawing.CreateLine(base.GraphicsDevice, (Int32)base.Location.X, (Int32)base.Location.Y, (Int32)base.Location.X + (Int32)base.Size.X, 1, Color.White);
            base.LoadContent();
        }

        public override void Update(GameTime gameTime, TouchCollection touches)
        {
            if (touches.Count > 0)
            {
                TouchLocation touch = touches[0];
                switch (touch.State)
                {
                    case TouchLocationState.Pressed:
                        _startPos = touch.Position;
                        _touchChangedIndex = false;
                        break;
                    case TouchLocationState.Moved:
                        //_isMoving = true;
                        //if start.X > 204 (75%) of the width, and current.X < 109 (40%) of the width, go to previous:
                        if (_startPos.X > 163 && touch.Position.X < 109 && !_touchChangedIndex)
                        {
                            SetNextTabPage();
                            _touchChangedIndex = true;
                        }

                        //if start.X < 68 (25%) of the width, and current.X > 163 (60%) of the width, go to next:
                        if (_startPos.X < 109 && touch.Position.X > 163 && !_touchChangedIndex)
                        {
                            SetPreviousTabPage();
                            _touchChangedIndex = true;
                        }
                        break;
                    case TouchLocationState.Released:
                        //_isMoving = false;
                        break;
                }

            }

            base.Update(gameTime, touches);
        }

        public override void Draw(GameTime gameTime)
        {
            if (base.Visible)
            {
                if (_currentTabIndex == -1)
                {
                    //_currentTabIndex = 0;
                    foreach (TabPage page in _tabPages)
                        page.DisplayControls(false);

                    SetNextTabPage();
                }

                _leftButton.Location = new Vector2(base.Location.X + 5, _headerHeight / 2 - _leftButton.Size.Y / 2 + 3);
                _rightButton.Location = new Vector2(base.Location.X + base.Size.X - 5 - _rightButton.Size.X, _headerHeight / 2 - _rightButton.Size.Y / 2 + 3);
                _headerLabel.Location = new Vector2(base.Location.X + 5 + _leftButton._size.X, _location.Y + 3);
                _headerLabel.Size = new Vector2(_size.X - 10 - _rightButton._size.X - _leftButton._size.X, _headerLabel._size.Y);

                DrawMainTabTitles();

                base.Draw(gameTime);

                _tabPages[_currentTabIndex].Draw(gameTime);
            }
        }
        #endregion

        #region Internal Methods
        private void DrawMainTabTitles()
        {
            if (_tabPages[_currentTabIndex] != null)
            {
                string name = _tabPages[_currentTabIndex].Text;
                Vector2 textStartPos = Utilities.CenterTextVector2(_font, name, base.Location, new Vector2(base.Size.X, _headerHeight));

                //Draw Previous arrow?
                if (_currentTabIndex > 0)
                {
                    _leftButton.Visible = true;
                }
                else
                {
                    _leftButton.Visible = false;
                }

                _headerLabel.Font = _font;
                _headerLabel.Text = name;

                //_headerLabel.Location = textStartPos;
                _headerLabel.ForeColor = base.ForeColor;

                //SpriteBatch.DrawString(_font, name, textStartPos, base.ForeColor);

                //Draw Next Arrow?
                if (_currentTabIndex < _tabPages.Count-1)
                {
                    _rightButton.Visible = true;
                }
                else
                {
                    _rightButton.Visible = false;
                }

                SpriteBatch.Draw(_headerSeperatorLine, new Vector2(_location.X, _headerHeight + 1), Color.White);
            }
        }

        private void SetContextMenuItemDisabled()
        {
            string text = _tabPages[_currentTabIndex].Text;
            foreach (MenuItem mi in _contextMenu._menuItems)
            {
                if (mi.Text == text)
                    mi.Enabled = false;
                else
                    mi.Enabled = true;
            }
        }

        private void SetNextTabPage()
        {
            if (_currentTabIndex < _tabPages.Count - 1)
            {
                //First, set all current tab page controls to not visible
                if (_currentTabIndex > -1)
                    _tabPages[_currentTabIndex].DisplayControls(false);
                _currentTabIndex++;
                _tabPages[_currentTabIndex].DisplayControls(true);
                SetContextMenuItemDisabled();
            }
        }

        private void SetPreviousTabPage()
        {
            if (_currentTabIndex > 0)
            {
                //First, set all current tab page controls to not visible
                _tabPages[_currentTabIndex].DisplayControls(false);
                _currentTabIndex--;
                _tabPages[_currentTabIndex].DisplayControls(true);
                SetContextMenuItemDisabled();
            }
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the TabPage that is selected.
        /// </summary>
        public int SelectedTabIndex
        {
            get { return _currentTabIndex; }
            set 
            {
                //int temp = _currentTabIndex;
                //_currentTabIndex = value; 
                if (value < _currentTabIndex)
                {
                    SetPreviousTabPage();
                }
                else if (value > _currentTabIndex)
                {
                    SetNextTabPage();
                }
            }
        }

        /// <summary>
        /// Gets or sets the image to use for the Previous Button.  Must exist in the Content folder.
        /// </summary>
        public string PreviousImage
        {
            get { return _leftButton.BackgroundImage; }
            set { _leftButton.BackgroundImage = value; }
        }

        /// <summary>
        /// Gets or sets the image to use for the Previous Button in its pressed state.  Must exist in the Content folder.
        /// </summary>
        public string PreviousImagePressed
        {
            get { return _leftButton.BackgroundImagePressed; }
            set { _leftButton.BackgroundImagePressed = value; }
        }

        /// <summary>
        /// Gets or sets the image to use for the Next Button.  Must exist in the Content folder.
        /// </summary>
        public string NextImage
        {
            get { return _rightButton.BackgroundImage; }
            set { _rightButton.BackgroundImage = value; }
        }

        /// <summary>
        /// Gets or sets the image to use for the Next Button in its pressed state.  Must exist in the Content folder.
        /// </summary>
        public string NextImagePressed
        {
            get { return _rightButton.BackgroundImagePressed; }
            set { _rightButton.BackgroundImagePressed = value; }
        }

        /// <summary>
        /// Gets or sets whether the header is displayed.
        /// </summary>
        public bool DisplayHeader
        {
            get { return _showHeader; }
            set
            {
                _showHeader = value;
                if (_showHeader)
                    _headerHeight = 50;
                else
                    _headerHeight = 0;
            }
        }
        #endregion
    }
}